package co.yixiang.yshop.module.crm.util;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;

import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 动态Excel导出工具类
 * 支持根据选择的列动态生成Excel
 */
public class DynamicExcelExportUtil {

    /**
     * 动态导出Excel
     * @param response HTTP响应
     * @param fileName 文件名
     * @param sheetName 工作表名
     * @param data 数据列表
     * @param selectedColumns 选中的列
     * @param clazz 导出VO类
     * @param <T> 泛型类型
     */
    public static <T> void write(HttpServletResponse response, String fileName, String sheetName, 
                                List<T> data, Set<String> selectedColumns, Class<T> clazz) throws IOException {
        
        // 设置响应头
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName);
        
        // 创建样式策略
        HorizontalCellStyleStrategy styleStrategy = createStyleStrategy();
        
        // 获取需要导出的字段
        List<Field> exportFields = getExportFields(clazz, selectedColumns);
        
        // 创建动态表头
        List<List<String>> headList = createDynamicHead(exportFields);
        
        // 转换数据
        List<List<Object>> dataList = convertDataToDynamicFormat(data, exportFields);
        
        // 写入Excel
        EasyExcel.write(response.getOutputStream())
                .head(headList)
                .registerWriteHandler(styleStrategy)
                .sheet(sheetName)
                .doWrite(dataList);
    }
    
    /**
     * 获取需要导出的字段
     */
    private static List<Field> getExportFields(Class<?> clazz, Set<String> selectedColumns) {
        List<Field> allFields = Arrays.asList(clazz.getDeclaredFields());
        
        // 如果没有指定列，导出所有字段
        if (selectedColumns == null || selectedColumns.isEmpty()) {
            return allFields.stream()
                    .filter(field -> field.isAnnotationPresent(com.alibaba.excel.annotation.ExcelProperty.class))
                    .collect(Collectors.toList());
        }
        
        // 根据选中的列过滤字段
        return allFields.stream()
                .filter(field -> {
                    com.alibaba.excel.annotation.ExcelProperty excelProperty = 
                            field.getAnnotation(com.alibaba.excel.annotation.ExcelProperty.class);
                    if (excelProperty == null) return false;
                    
                    // 检查字段名是否在选中列中
                    return selectedColumns.contains(field.getName());
                })
                .collect(Collectors.toList());
    }
    
    /**
     * 创建动态表头
     */
    private static List<List<String>> createDynamicHead(List<Field> exportFields) {
        return exportFields.stream()
                .map(field -> {
                    com.alibaba.excel.annotation.ExcelProperty excelProperty = 
                            field.getAnnotation(com.alibaba.excel.annotation.ExcelProperty.class);
                    String[] value = excelProperty.value();
                    return Arrays.asList(value);
                })
                .collect(Collectors.toList());
    }
    
    /**
     * 转换数据为动态格式
     */
    private static <T> List<List<Object>> convertDataToDynamicFormat(List<T> data, List<Field> exportFields) {
        return data.stream()
                .map(item -> exportFields.stream()
                        .map(field -> {
                            try {
                                field.setAccessible(true);
                                Object value = field.get(item);
                                return value != null ? value : "";
                            } catch (IllegalAccessException e) {
                                return "";
                            }
                        })
                        .collect(Collectors.toList()))
                .collect(Collectors.toList());
    }
    
    /**
     * 创建样式策略
     */
    private static HorizontalCellStyleStrategy createStyleStrategy() {
        // 表头样式
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 12);
        headWriteFont.setBold(true);
        headWriteCellStyle.setWriteFont(headWriteFont);
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        
        // 内容样式
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    }
}
